//+------------------------------------------------------------------+
//|                                                    Indicator.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include "Series.h"

//+------------------------------------------------------------------+
//| 指标缓冲区类                                                     |
//| 用途：用于访问技术指标缓冲区的数据                               |
//|         继承自 CDoubleBuffer 类                                  |
//+------------------------------------------------------------------+
class CIndicatorBuffer : public CDoubleBuffer
{
protected:
   int               m_offset;           // 时间轴偏移（以柱为单位）
   string            m_name;             // 缓冲区名称

public:
   /** 构造函数 */
   CIndicatorBuffer(void);
   
   /** 析构函数 */
   ~CIndicatorBuffer(void);
   
   /** 获取偏移量 */
   int               Offset(void)        const;
   
   /** 设置偏移量 */
   void              Offset(const int offset);
   
   /** 获取缓冲区名称 */
   string            Name(void)          const;
   
   /** 设置缓冲区名称 */
   void              Name(const string name);
   
   /**
    * 访问指定位置的数据
    * @param index 索引位置
    * @return 数据值
    */
   double            At(const int index) const;
   
   /**
    * 刷新缓冲区数据
    * @param handle 指标句柄
    * @param num 缓冲区编号
    * @return 成功返回 true，失败返回 false
    */
   bool              Refresh(const int handle, const int num);
   
   /**
    * 刷新当前缓冲区数据
    * @param handle 指标句柄
    * @param num 缓冲区编号
    * @return 成功返回 true，失败返回 false
    */
   bool              RefreshCurrent(const int handle, const int num);

private:
   /** 刷新缓冲区（覆盖基类方法） */
   virtual bool      Refresh(void);
   
   /** 刷新当前缓冲区（覆盖基类方法） */
   virtual bool      RefreshCurrent(void);
};

//+------------------------------------------------------------------+
//| 指标基类                                                         |
//| 用途：技术指标的基类                                             |
//|         继承自 CSeries 类                                        |
//+------------------------------------------------------------------+
class CIndicator : public CSeries
{
protected:
   int               m_handle;           // 指标句柄
   string            m_status;           // 创建状态
   bool              m_full_release;     // 完全释放标志
   bool              m_redrawer;         // 重绘标志

public:
   /** 构造函数 */
   CIndicator(void);
   
   /** 析构函数 */
   ~CIndicator(void);
   
   /** 获取指标句柄 */
   int               Handle(void) const;
   
   /** 获取创建状态 */
   string            Status(void) const;
   
   /** 设置完全释放标志 */
   void              FullRelease(const bool flag = true);
   
   /** 设置重绘标志 */
   void              Redrawer(const bool flag = true);
   
   /**
    * 创建指标
    * @param symbol 交易品种名称
    * @param period 时间周期
    * @param type 指标类型
    * @param num_params 参数数量
    * @param params 参数数组
    * @return 成功返回 true，失败返回 false
    */
   bool              Create(const string symbol, const ENUM_TIMEFRAMES period,
                            const ENUM_INDICATOR type, const int num_params, const MqlParam &params[]);
   
   /**
    * 调整指标缓冲区大小
    * @param size 新的大小
    * @return 成功返回 true，失败返回 false
    */
   virtual bool      BufferResize(const int size);
   
   /**
    * 获取已计算的指标柱数
    * @return 柱数
    */
   int               BarsCalculated(void) const;
   
   /**
    * 获取指定缓冲区的数据
    * @param buffer_num 缓冲区编号
    * @param index 索引位置
    * @return 数据值
    */
   double            GetData(const int buffer_num, const int index) const;
   
   /**
    * 获取指定缓冲区的数据（通过起始位置和数量）
    * @param start_pos 起始位置
    * @param count 数量
    * @param buffer_num 缓冲区编号
    * @param buffer 输出缓冲区
    * @return 复制的数据数量
    */
   int               GetData(const int start_pos, const int count, const int buffer_num, double &buffer[]) const;
   
   /**
    * 获取指定缓冲区的数据（通过起始时间和数量）
    * @param start_time 起始时间
    * @param count 数量
    * @param buffer_num 缓冲区编号
    * @param buffer 输出缓冲区
    * @return 复制的数据数量
    */
   int               GetData(const datetime start_time, const int count, const int buffer_num, double &buffer[]) const;
   
   /**
    * 获取指定缓冲区的数据（通过起始时间和结束时间）
    * @param start_time 起始时间
    * @param stop_time 结束时间
    * @param buffer_num 缓冲区编号
    * @param buffer 输出缓冲区
    * @return 复制的数据数量
    */
   int               GetData(const datetime start_time, const datetime stop_time, const int buffer_num, double &buffer[]) const;
   
   /**
    * 查找指定缓冲区的最小值位置
    * @param buffer_num 缓冲区编号
    * @param start 起始位置
    * @param count 数量
    * @return 最小值位置
    */
   int               Minimum(const int buffer_num, const int start, const int count) const;
   
   /**
    * 查找指定缓冲区的最小值
    * @param buffer_num 缓冲区编号
    * @param start 起始位置
    * @param count 数量
    * @param index 输出最小值位置
    * @return 最小值
    */
   double            MinValue(const int buffer_num, const int start, const int count, int &index) const;
   
   /**
    * 查找指定缓冲区的最大值位置
    * @param buffer_num 缓冲区编号
    * @param start 起始位置
    * @param count 数量
    * @return 最大值位置
    */
   int               Maximum(const int buffer_num, const int start, const int count) const;
   
   /**
    * 查找指定缓冲区的最大值
    * @param buffer_num 缓冲区编号
    * @param start 起始位置
    * @param count 数量
    * @param index 输出最大值位置
    * @return 最大值
    */
   double            MaxValue(const int buffer_num, const int start, const int count, int &index) const;
   
   /**
    * 刷新指标数据
    * @param flags 刷新标志
    */
   virtual void      Refresh(const int flags = OBJ_ALL_PERIODS);
   
   /**
    * 将指标添加到图表
    * @param chart 图表ID
    * @param subwin 子窗口索引
    * @return 成功返回 true，失败返回 false
    */
   bool              AddToChart(const long chart, const int subwin);
   
   /**
    * 从图表删除指标
    * @param chart 图表ID
    * @param subwin 子窗口索引
    * @return 成功返回 true，失败返回 false
    */
   bool              DeleteFromChart(const long chart, const int subwin);
   
   /**
    * 将均线方法转换为描述字符串
    * @param val 均线方法枚举值
    * @return 描述字符串
    */
   static string     MethodDescription(const int val);
   
   /**
    * 将应用价格转换为描述字符串
    * @param val 应用价格枚举值
    * @return 描述字符串
    */
   static string     PriceDescription(const int val);
   
   /**
    * 将成交量类型转换为描述字符串
    * @param val 成交量类型枚举值
    * @return 描述字符串
    */
   static string     VolumeDescription(const int val);

protected:
   /**
    * 创建指标缓冲区
    * @param symbol 交易品种名称
    * @param period 时间周期
    * @param buffers 缓冲区数量
    * @return 成功返回 true，失败返回 false
    */
   bool              CreateBuffers(const string symbol, const ENUM_TIMEFRAMES period, const int buffers);
   
   /**
    * 初始化指标
    * @param symbol 交易品种名称
    * @param period 时间周期
    * @param num_params 参数数量
    * @param params 参数数组
    * @return 成功返回 true，失败返回 false
    */
   virtual bool      Initialize(const string symbol, const ENUM_TIMEFRAMES period,
                                const int num_params, const MqlParam &params[]);
};
//+------------------------------------------------------------------+